home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / include / sun3.md / math-68881.h < prev    next >
C/C++ Source or Header  |  1990-09-17  |  9KB  |  390 lines

  1.  
  2. /*******************************************************************
  3. *                                                                  *
  4. *  <math-68881.h>               last modified: March 22, 1989.     *
  5. *                                                                  *
  6. *  Copyright (C) 1989 by Matthew Self.                             *
  7. *  You may freely distribute verbatim copies of this software      *
  8. *  provided that this copyright notice is retained in all copies.  *
  9. *  You may distribute modifications to this software under the     *
  10. *  conditions above if you also clearly note such modifications    *
  11. *  with their author and date.                                     *
  12. *                                                                  *
  13. *  Note:  errno is not set to EDOM when domain errors occur for    *
  14. *  most of these functions.  Rather, it is assumed that the        *
  15. *  68881's OPERR exception will be enabled and handled             *
  16. *  appropriately by the operating system.  Similarly, overflow     *
  17. *  and underflow do not set errno to ERANGE.                       *
  18. *                                                                  *
  19. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).            *
  20. *                                                                  *
  21. *******************************************************************/
  22.  
  23. #ifndef __asm
  24. #define __asm asm               /* until new __asm is done */
  25. #endif
  26.  
  27. #ifndef __inline
  28. #define __inline inline         /* until new __inline is done */
  29. #endif
  30.  
  31. #include <errno.h>
  32.  
  33. #ifndef HUGE_VAL
  34. #define HUGE_VAL                                                        \
  35. ({                                                                      \
  36.   double huge_val;                                                      \
  37.                                                                         \
  38.   __asm ("fmove%.d #0x7ff0000000000000,%0"      /* Infinity */          \
  39.          : "=f" (huge_val)                                              \
  40.          : /* no inputs */);                                            \
  41.   huge_val;                                                             \
  42. })
  43. #endif
  44.  
  45. __inline static const double sin (double x)
  46. {
  47.   double value;
  48.  
  49.   __asm ("fsin%.x %1,%0"
  50.          : "=f" (value)
  51.          : "f" (x));
  52.   return value;
  53. }
  54.  
  55. __inline static const double cos (double x)
  56.   double value;
  57.  
  58.   __asm ("fcos%.x %1,%0"
  59.          : "=f" (value)
  60.          : "f" (x));
  61.   return value;
  62. }
  63.  
  64. __inline static const double tan (double x)
  65. {
  66.   double value;
  67.  
  68.   __asm ("ftan%.x %1,%0"
  69.          : "=f" (value)
  70.          : "f" (x));
  71.   return value;
  72. }
  73.  
  74. __inline static const double asin (double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("fasin%.x %1,%0"
  79.          : "=f" (value)
  80.          : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static const double acos (double x)
  85. {
  86.   double value;
  87.  
  88.   __asm ("facos%.x %1,%0"
  89.          : "=f" (value)
  90.          : "f" (x));
  91.   return value;
  92. }
  93.  
  94. __inline static const double atan (double x)
  95. {
  96.   double value;
  97.  
  98.   __asm ("fatan%.x %1,%0"
  99.          : "=f" (value)
  100.          : "f" (x));
  101.   return value;
  102. }
  103.  
  104. __inline static const double atan2 (double y, double x)
  105. {
  106.   double pi, pi_over_2;
  107.  
  108.   __asm ("fmovecr%.x %#0,%0"            /* extended precision pi */
  109.          : "=f" (pi)
  110.          : /* no inputs */ );
  111.   __asm ("fscale%.b %#-1,%0"            /* no loss of accuracy */
  112.          : "=f" (pi_over_2)
  113.          : "0" (pi));
  114.   if (x > 0)
  115.     {
  116.       if (y > 0)
  117.         {
  118.           if (x > y)
  119.             return atan (y / x);
  120.           else
  121.             return pi_over_2 - atan (x / y);
  122.         }
  123.       else
  124.         {
  125.           if (x > -y)
  126.             return atan (y / x);
  127.           else
  128.             return - pi_over_2 - atan (x / y);
  129.         }
  130.     }
  131.   else
  132.     {
  133.       if (y > 0)
  134.         {
  135.           if (-x > y)
  136.             return pi + atan (y / x);
  137.           else
  138.             return pi_over_2 - atan (x / y);
  139.         }
  140.       else
  141.         {
  142.           if (-x > -y)
  143.             return - pi + atan (y / x);
  144.           else if (y < 0)
  145.             return - pi_over_2 - atan (x / y);
  146.           else
  147.             {
  148.               double value;
  149.  
  150.               errno = EDOM;
  151.               __asm ("fmove%.d %#0rnan,%0"      /* quiet NaN */
  152.                      : "=f" (value)
  153.                      : /* no inputs */);
  154.               return value;
  155.             }
  156.         }
  157.     }
  158. }
  159.  
  160. __inline static const double sinh (double x)
  161. {
  162.   double value;
  163.  
  164.   __asm ("fsinh%.x %1,%0"
  165.          : "=f" (value)
  166.          : "f" (x));
  167.   return value;
  168. }
  169.  
  170. __inline static const double cosh (double x)
  171. {
  172.   double value;
  173.  
  174.   __asm ("fcosh%.x %1,%0"
  175.          : "=f" (value)
  176.          : "f" (x));
  177.   return value;
  178. }
  179.  
  180. __inline static const double tanh (double x)
  181. {
  182.   double value;
  183.  
  184.   __asm ("ftanh%.x %1,%0"
  185.          : "=f" (value)
  186.          : "f" (x));
  187.   return value;
  188. }
  189.  
  190. __inline static const double exp (double x)
  191. {
  192.   double value;
  193.  
  194.   __asm ("fetox%.x %1,%0"
  195.          : "=f" (value)
  196.          : "f" (x));
  197.   return value;
  198. }
  199.  
  200. __inline static const double log (double x)
  201. {
  202.   double value;
  203.  
  204.   __asm ("flogn%.x %1,%0"
  205.          : "=f" (value)
  206.          : "f" (x));
  207.   return value;
  208. }
  209.  
  210. __inline static const double log10 (double x)
  211. {
  212.   double value;
  213.  
  214.   __asm ("flog10%.x %1,%0"
  215.          : "=f" (value)
  216.          : "f" (x));
  217.   return value;
  218. }
  219.  
  220. __inline static const double pow (const double x, const double y)
  221. {
  222.   if (x > 0)
  223.     return exp (y * log (x));
  224.   else if (x == 0)
  225.     {
  226.       if (y > 0)
  227.         return 0.0;
  228.       else
  229.         {
  230.           double value;
  231.  
  232.           errno = EDOM;
  233.           __asm ("fmove%.d %#0rnan,%0"          /* quiet NaN */
  234.                  : "=f" (value)
  235.                  : /* no inputs */);
  236.           return value;
  237.         }
  238.     }
  239.   else
  240.     {
  241.       double temp;
  242.  
  243.       __asm ("fintrz%.x %1,%0"
  244.              : "=f" (temp)                      /* integer-valued float */
  245.              : "f" (y));
  246.       if (y == temp)
  247.         {
  248.           int i = (int) y;
  249.  
  250.           if (i & 1 == 0)                       /* even */
  251.             return exp (y * log (x));
  252.           else
  253.             return - exp (y * log (x));
  254.         }
  255.       else
  256.         {
  257.           double value;
  258.  
  259.           errno = EDOM;
  260.           __asm ("fmove%.d %#0rnan,%0"          /* quiet NaN */
  261.                  : "=f" (value)
  262.                  : /* no inputs */);
  263.           return value;
  264.         }
  265.     }
  266. }
  267.  
  268. __inline static const double sqrt (double x)
  269. {
  270.   double value;
  271.  
  272.   __asm ("fsqrt%.x %1,%0"
  273.          : "=f" (value)
  274.          : "f" (x));
  275.   return value;
  276. }
  277.  
  278. __inline static const double ceil (double x)
  279. {
  280.   int rounding_mode, round_up;
  281.   double value;
  282.  
  283.   __asm volatile ("fmove%.l fpcr,%0"
  284.                   : "=dm" (rounding_mode)
  285.                   : /* no inputs */ );
  286.   round_up = rounding_mode | 0x30;
  287.   __asm volatile ("fmove%.l %0,fpcr"
  288.                   : /* no outputs */
  289.                   : "dmi" (round_up));
  290.   __asm volatile ("fint%.x %1,%0"
  291.                   : "=f" (value)
  292.                   : "f" (x));
  293.   __asm volatile ("fmove%.l %0,fpcr"
  294.                   : /* no outputs */
  295.                   : "dmi" (rounding_mode));
  296.   return value;
  297. }
  298.  
  299. __inline static const double floor (double x)
  300. {
  301.   int rounding_mode, round_down;
  302.   double value;
  303.  
  304.   __asm volatile ("fmove%.l fpcr,%0"
  305.                   : "=dm" (rounding_mode)
  306.                   : /* no inputs */ );
  307.   round_down = (rounding_mode & ~0x10)
  308.                 | 0x20;
  309.   __asm volatile ("fmove%.l %0,fpcr"
  310.                   : /* no outputs */
  311.                   : "dmi" (round_down));
  312.   __asm volatile ("fint%.x %1,%0"
  313.                   : "=f" (value)
  314.                   : "f" (x));
  315.   __asm volatile ("fmove%.l %0,fpcr"
  316.                   : /* no outputs */
  317.                   : "dmi" (rounding_mode));
  318.   return value;
  319. }
  320.  
  321. #ifndef fabs
  322. __inline static const double fabs (double x)
  323. {
  324.   double value;
  325.  
  326.   __asm ("fabs%.x %1,%0"
  327.          : "=f" (value)
  328.          : "f" (x));
  329.   return value;
  330. }
  331. #endif
  332.  
  333. __inline static const double fmod (double x, double y)
  334. {
  335.   double value;
  336.  
  337.   __asm ("fmod%.x %2,%0"
  338.          : "=f" (value)
  339.          : "0" (x),
  340.            "f" (y));
  341.   return value;
  342. }
  343.  
  344. __inline static const double ldexp (double x, int n)
  345. {
  346.   double value;
  347.  
  348.   __asm ("fscale%.l %2,%0"
  349.          : "=f" (value)
  350.          : "0" (x),
  351.            "dmi" (n));
  352.   return value;
  353. }
  354.  
  355. __inline static double frexp (double x, int *exp)
  356. {
  357.   double float_exponent;
  358.   int int_exponent;
  359.   double mantissa;
  360.  
  361.   __asm ("fgetexp%.x %1,%0"
  362.          : "=f" (float_exponent)        /* integer-valued float */
  363.          : "f" (x));
  364.   int_exponent = (int) float_exponent;
  365.   __asm ("fgetmant%.x %1,%0"
  366.          : "=f" (mantissa)              /* 1.0 <= mantissa < 2.0 */
  367.          : "f" (x));
  368.   if (mantissa != 0)
  369.     {
  370.       __asm ("fscale%.b %#-1,%0"
  371.              : "=f" (mantissa)          /* mantissa /= 2.0 */
  372.              : "0" (mantissa));
  373.       int_exponent += 1;
  374.     }
  375.   *exp = int_exponent;
  376.   return mantissa;
  377. }
  378.  
  379. __inline static double modf (double x, double *ip)
  380.                 /* ip means "integer part" */
  381. {
  382.   __asm ("fintrz%.x %1,%0"
  383.          : "=f" (*ip)        /* integer-valued float */
  384.          : "f" (x));
  385.   return x - (*ip);
  386. }
  387.  
  388.  
  389.